/*
----------------------------------------------------------------------------------------------------
This source file is part of the Gamut Framework
Copyright (c) 2007 by Ryan Holcombe

This program is free software; you can redistribute it and/or modify it under the terms of the GNU
Lesser General Public License as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
----------------------------------------------------------------------------------------------------
*/


#include "GamutConsole.h"
#include "GamutLogger.h"
#include <sstream>
#include <iterator>
#include <string>


namespace Gamut
{
	
	//! Declare Singleton
	template<> Console* Singleton<Console>::ms_Singleton = 0;
	
	// -------------------------------------------------------------------------------------------//
	Console::Console()
	{
		LOGF4("Singleton Console (%p) created", this);
	}
	
	// -------------------------------------------------------------------------------------------//
	Console::~Console()
	{
		LOGF4("Singleton Console (%p) destroyed", this);
	}

	// -------------------------------------------------------------------------------------------//
	bool Console::registerCallback(std::string name, ConsoleCallback fptr)
	{
		if (m_callback.find(name) != m_callback.end())
		{
			LOG2("Console function " + name + " already exists in the map");
			return (0);
		}
		
		m_callback.insert(std::make_pair<std::string, ConsoleCallback>(name, fptr));
		LOG4("Console callback command " + name + " added to map");
		
		return (1);
	}
	
	// -------------------------------------------------------------------------------------------//
	void Console::removeCallback(std::string name)
	{
		CallbackMap::iterator iter = m_callback.find(name);
		
		if (iter != m_callback.end())
			m_callback.erase(iter);
		else
			LOG2("Unable to find console function " + name + " in the map");
		
		LOG4("Console callback command " + name + " removed from map");
	}
	
	// -------------------------------------------------------------------------------------------//
	bool Console::executeCallback(std::string command)
	{
		ConsoleArgs args;
		
		// split the string
		std::istringstream is(command);
		args = ConsoleArgs(std::istream_iterator<std::string>(is), std::istream_iterator<std::string>());
		
		// extract the command name
		CallbackMap::iterator iter = m_callback.find(args[0]);
		
		if (iter == m_callback.end())
		{
			LOG2("Unable to find console function " + args[0] + " in the map");
			return (1);
		}
		
		// erase the command name from the argument list
		args.erase(args.begin());
		
		// validate the function
		if (!iter->second)
		{
			LOG2("Console function " + iter->first + " is no longer valid");
			return (1);
		}
		
		return (iter->second)(args);
	}
	
	// -------------------------------------------------------------------------------------------//
	CallbackList Console::getCallbackList()
	{
		CallbackList list;

		for (CallbackMap::iterator iter = m_callback.begin(); iter != m_callback.end(); iter++)
			list.push_back(iter->first);

		return (list);
	}
}

